/*
 *      BenchMark.c -   measure the speed of compiler-generated code
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TIME_TARGET             2.0             /* target execution time */


/*
 *      return elapsed time between now and the time passed in.
 *      One should use an arg of 0.0 first to get elapsed time ie.,
 *
 *              start = TimeSince( 0.0 );
 *              Compute();
 *              elapsed = TimeSince( start );
 */

double pow(double x, int y)
{
    double result = x;
    int count;
    for (count = 1; count < y; count++) {
	result = result * x;
    }
    return result;
}

double cos(double angle)
{
    double result;
    result = 1 - (pow(angle,2)/2) + (pow(angle,4)/24) -
	(pow(angle,6)/720) + (pow(angle,8)/40320); 
    return result;
}

double sin(double angle)
{
    double result;
    result = angle - (pow(angle,3)/6) + (pow(angle,5)/120) -
	(pow(angle,7)/5040) + (pow(angle,9)/362880); 
    return result;
}

/*/////////////////// Floating Point Benchmark ////////////////////////*/


void DoFloatTest( int loops )
{
    double  start;
    double  elapsed;
    double  tmp1;
    double  tmp2;
    double  x;
    double  y;
    double  A;
    double  B;
    double  AB;
    double  AplusB;
    double  scaleA;
    double  G;
    double  angle;
    double  incr;
    double  gincr;
    double  gangle;
    double  scale;
    int             ndx;

    /* compute temporaries */

    B = 2.5;
    A = 4.1;
    scale = 100.0;
    incr = 0.14;

    AB = A * B;
    AB *= scale;
    scaleA = scale * A;
    AplusB = A + B;

    G = A + B;
    G /= B;
    gincr = G * incr;

    gangle = 0;
    angle = 0;
        
    for( ndx = 0; ndx < loops; ndx += 1 )
    {
	tmp1 = cos(angle);
	tmp1 *= AplusB;

	tmp2 = sin(gangle);
	tmp2 *= B;

	tmp1 += tmp2;
	tmp1 *= scale;
	x = tmp1;

	tmp1 = sin(angle);
	tmp1 *= AplusB;

	tmp2 = cos(gangle);
	tmp2 *= B;

	tmp1 -= tmp2;
	tmp1 *= scale;
	y = tmp1;

	gangle += gincr;
	angle += incr;
    }
    printf("G Value = %f\n",gangle);
    printf("Value = %f\n",angle);
}

void FloatSpeedTest()
{
    int             count;

    printf( "beginning floating point test :\n\n" );
    count = 40000;
    DoFloatTest( count );
}


/*/////////////////// Integer Loop Benchmark //////////////////////////*/


int TestFunc( int a1, double a2, char *a3 ) {
    int temp;
    temp = (((a1*2)+2)/2);
    return temp;
}

void DoIntTest( int *imax, int *ival, double *dval, char **sval )
{
    int count;
    int *pcount;
    int leftovers;
    leftovers = 0;
    count = 0;
    pcount = &count;  
    while( *pcount < *imax ) {
	*ival = TestFunc(*ival, *dval, *sval);
	*ival = *ival * 3;
	leftovers = leftovers + (*ival % 2);
	*ival = *ival / 3;
	( *pcount ) += 1;
    }
    printf("IVal = %d\n",*ival);
    printf("IVal2 = %d\n\n",leftovers);
  
}

void IntSpeedTest()
{
    double  dval = 3.14159;
    char *  sval = "a string";
    int     ival = 42;
    int     count = 500000;

    printf( "beginning integer test :\n\n" );
    DoIntTest( &count, &ival, &dval, &sval );
}

int main( int ac, char *av[] )
{
    printf( "\n" );
    IntSpeedTest();
    FloatSpeedTest();
    return 0;
}
